package com.xframe.common.core.aop;


import com.xframe.xdal.core.tran.DbTransactionContext;
import com.xframe.xdal.core.tran.TransactionIsolation;
import com.xframe.xdal.core.tran.XTransaction;
import com.xframe.xdal.core.util.XReflect;
import lombok.extern.log4j.Log4j2;

/**
 * 事务AOP切面对象
 *
 * @author xufeng
 * @version 1.0
 * @date 2022-09-28
 */
@Log4j2
public class XTransactionDecoration extends BaseDecoration{
    private boolean isNewTran = false;
    private XTransaction xTransaction = null;


    public XTransactionDecoration(){
        this.execOrder = 100;
    }

    @Override
    public boolean testMethod(XAOPContext context) {
        xTransaction = XReflect.getMethodTransaction(context.getMethod());
        return xTransaction != null;
    }

    @Override
    public void init(XAOPContext context) {
        super.init(context);
    }

    @Override
    public void beforeExecution(XAOPContext context) {
        if (!DbTransactionContext.hasDbTransaction()) {
            // 没有事务则开启一个新的
            int tranLevel = xTransaction.tranLevel();
            if(tranLevel == TransactionIsolation.TRANSACTION_READ_COMMITTED || tranLevel == TransactionIsolation.TRANSACTION_READ_UNCOMMITTED ||
                    tranLevel == TransactionIsolation.TRANSACTION_REPEATABLE_READ || tranLevel == TransactionIsolation.TRANSACTION_SERIALIZABLE)
            {
                context.getRepository().beginTransaction(tranLevel);
            }else {
                context.getRepository().beginTransaction();
            }
            isNewTran = true;
        }
        super.beforeExecution(context);
    }

    @Override
    public void afterExecution(XAOPContext context) {
        super.afterExecution(context);
    }

    @Override
    public void finallyComplete(XAOPContext context) {
        if (isNewTran) {
            context.getRepository().commitTran();
        }
        super.finallyComplete(context);
    }

    @Override
    public void exceptionHandler(XAOPContext context){
        if (isNewTran) {
            context.getRepository().rollBackTran();
        }
        super.exceptionHandler(context);
    }

    @Override
    public BaseDecoration buildeNew() {
        return new XTransactionDecoration();
    }


}
